#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <unistd.h>
#include <pthread.h>

//线程的局部存储
__thread int shared_value = 100;

std::string toHex(pthread_t tid)
{
    //4.进程内的函数，线程共享
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}

void *start(void *args)
{
    std::string name = static_cast<const char *>(args);
    sleep(1);
    while(true)
    {
        printf("I am a new thread, name: %s, shared_value: %d, &share_value: %p\n",
            name.c_str(), shared_value, &shared_value);
        sleep(1);
    }

    return nullptr;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, start, (void*)"thread-1");
    std::cout << "I am a new thread, name:main, " << toHex(pthread_self()) 
            << ", New thread id" << toHex(tid) << std::endl;

    while(true)
    {
        printf("main thread, shared_value: %d, &share_value: %p\n",
            shared_value, &shared_value);
        shared_value += 10;
        sleep(1);
    }
    pthread_join(tid, nullptr);

    return 0;
}







// class ThreadData
// {
// public:
//     ThreadData(){}
//
//     void Init(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }
//
//     void Excute()
//     {
//         _result =  _a + _b;
//     }
//
//     int Result()
//     {
//         return _result;
//     }
//
//     std::string Name()
//     {
//         return _name;
//     }
//
//     void Setid(pthread_t tid)
//     {
//         _tid = tid;
//     }
//
//     pthread_t Id()
//     {
//         return _tid;
//     }
//
//     int A() { return _a;}
//     int B() { return _b;}
//
//     ~ThreadData()
//     {}
//
// private:
//     std::string _name;
//     int _a;
//     int _b;
//     int _result;
//     pthread_t _tid;
// };

// 5.全局变量在线程内部共享
// int g_val = 100;

// std::string toHex(pthread_t tid)
// {
//     //4.进程内的函数，线程共享
//     char buffer[64];
//     snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//     return buffer;
// }

// //函数被重入了
// void *routine2(void *args)
// {
//     //3.在不加保护的情况下，显示器文件就是共享资源
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         std::cout << "我是新线程，我的名字是: " << name << ", my tid is: " << toHex(pthread_self()) << "全局变量(做检测): " << g_val << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// void *routine(void *args)
// {
//     //3.在不加保护的情况下，显示器文件就是共享资源
//     ThreadData *td = static_cast<ThreadData *>(args);
//     while (true)
//     {
//         //std::cout << "我是新线程，我的名字是: " << td->Name() << ", my tid is: " << toHex(pthread_self()) << "全局变量(会修改): " << g_val << std::endl;
//         //g_val++;
//         std::cout << "我是新线程，我的名字是: " << td->Name() << ", my tid is: " << toHex(pthread_self()) << std::endl;
//         td->Excute();

//         sleep(1);
//         break;
//         // 6.线程一旦出现异常，可能会导致其他线程全部崩溃
//         // 6.1信号
//         // int *p = nullptr;
//         // *p = 1;
//     }
//     // 8. 返回值问题: 返回参数，可以是变量，数字和对象
//     // 8.1理论上，堆空间是共享的！谁拿着堆空间的入口地址，谁就能访问堆空间
//     //int *p = new int(10);
//     //return (void *)p; //线程退出方式1：线程入口函数return，表示函数退出

//     return td;
// }

// #define NUM 10

// int main()
// {
//     ThreadData td[NUM];
//     // 准备我们要加工的数据
//     for (int i = 0; i < NUM; i++)
//     {
//         char id[64];
//         snprintf(id, sizeof(id), "thread-%d", i);
//         td[i].Init(id, i*10, i*20);
//     }
    
//     //创建多线程
//     for(int i = 0; i < NUM; i++)
//     {
//         pthread_t id;
//         pthread_create(&id, nullptr, routine, &td[i]);
//         td[i].Setid(id);
//     }

//     //等待多个线程
//     for(int i = 0; i < NUM; i++)
//     {
//         pthread_join(td[i].Id(), nullptr);
//     }

//     //汇总处理结果
//     for(int i = 0; i < NUM; i++)
//     {
//         printf("td[%d]: %d+%d=%d[%ld]\n", i, td[i].A(), td[i].B(), td[i].Result(), td[i].Id());
//     }

//     // 1. 新线程和main线程谁先运行，不确定
//     // 2. 线程创建出来，要对进程的时间片进行瓜分
//     // 8. 传参问题: 传递参数可以是变量，数字和对象
//     // pthread_t tid1;
//     // ThreadData *td = new ThreadData("thread-1", 10, 20);
//     // pthread_create(&tid1, nullptr, routine1, td);

//     // // 7. 现成创建之后。也是要被等待和回收的！
//     // // 7.1理由：a.类似僵尸进程的问题  b.为了知道新线程的执行结果
//     // ThreadData *rtd = nullptr;
//     // //我们可以保证，执行完毕，任务一定处理完了，结果变量一定被写入了
//     // int n = pthread_join(tid1, (void **)&rtd);
//     // if(n != 0)
//     // {
//     //     std::cerr << "join error" << n << ", " << strerror(n) <<std::endl;
//     //     return 1;
//     // }
//     // std::cout << "join success, ret:" << rtd->Result() <<std::endl;
//     // delete td;

//     // pthread_t tid2;
//     // pthread_create(&tid2, nullptr, routine2, (void *)"thread-2");

//     // pthread_t tid3;
//     // pthread_create(&tid3, nullptr, routine, (void *)"thread-3");

//     // pthread_t tid4;
//     // pthread_create(&tid4, nullptr, routine, (void *)"thread-4");

//     // printf("new thread id: 0x%lx\n", tid1);
//     // printf("new thread id: 0x%lx\n", tid2);
//     // printf("new thread id: 0x%lx\n", tid3);
//     // printf("new thread id: 0x%lx\n", tid4);
//     // std::cout << "new thread id: " << tid << std::endl;

//     // while (true)
//     // {
//     //     std::cout << "我是main线程 " << std::endl;
//     //     sleep(1);
//     // }
// }

// // 新线程
// // void *routine(void *args)
// // {
// //     std::string name = static_cast<const char*>(args);
// //     while(true)
// //     {
// //         std::cout << "我是新线程，我的名字是: " << name << std::endl;
// //         sleep(1);
// //     }
// //     return nullptr;
// // }

// // int main()
// // {
// //     std::cout << "I am a process, pid:  " << getpid() << std::endl;

// //     pthread_t tid;
// //     int n = pthread_create(&tid, nullptr, routine, (void *)"thread-1");
// //     if(n != 0)
// //     {
// //         std::cout << "create thread error: " << strerror(n) << std::endl;
// //     }

// //     while(true)
// //     {
// //         std::cout << "我是main线程 "<< std::endl;
// //         sleep(1);
// //     }

// // }